﻿#include "StdAfx.h"
#include "lusb0_usb.h"
#include <stdio.h>
#include <Winsock2.h>

using namespace std;

#define DIGISPARKVID 0x16c0
#define DIGISPARKPID 0x05df

typedef union
{
	__int16 ivalue;
	byte bvalue[2];
}VOCDATA;

int upload_data_yeelink(char* hostname, char* apikey, char* deviceid, char* sensorid,int value)
{
	WSADATA WsaData;
	WSAStartup(0x0101, &WsaData);
	char valuestr[8];
	sprintf(valuestr,"%d",value);

	struct hostent* host_addr = gethostbyname(hostname);
	if (host_addr == NULL)
	{
		cout<<"Unable to locate host"<<endl;
		return -103;
	}

	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons((unsigned short)80);
	sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list);

	int sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == -1)
	{
		return -100;
	}

	if (connect(sock, (const struct sockaddr *)&sin, sizeof(sockaddr_in) ) == -1)
	{
		cout<<"connect failed"<<endl;
		return -101;
	}

	char send_str[2048] = {0};

	strcat(send_str, "POST /v1.0/device/");
	strcat(send_str, deviceid);
	strcat(send_str, "/sensor/");
	strcat(send_str, sensorid);
	strcat(send_str, "/datapoints HTTP/1.1\r\nHost: api.yeelink.net\r\nAccept: */*\r\nU-ApiKey:");
	strcat(send_str, apikey);
	strcat(send_str, "\r\nContent-Length: ");
	strcat(send_str, "14 ");
	strcat(send_str, "\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: close\r\n\r\n{\"value\":");
	strcat(send_str, valuestr);
	strcat(send_str, "}\r\n\r\n");

	if (send(sock, send_str, strlen(send_str),0) == -1)
	{
		return -101;
	}

	char recv_str[4096] = {0};
	if (recv(sock, recv_str, sizeof(recv_str), 0) == -1)
	{
		return -101;
	}
	WSACleanup( );
	return 0;
}
int main(int argc, char* argv[])
{
	int bus_count, device_count, result;
	char *apikey, *deviceid, *sensorid;
	char tmpchar=0;
	VOCDATA value;
	struct usb_dev_handle* p_handle = NULL;
	struct usb_bus *bus = NULL;
	struct usb_device *digispark = NULL;
	struct usb_interface_descriptor *p_interface = NULL;
	int numInterfaces = 0;
	bool isupload=false;

	if(argc==1)
	{
		isupload=false;
	}
	else if(argc == 4)
	{
		apikey = argv[1];
		deviceid = argv[2];
		sensorid= argv[3];
		isupload = true;
	}
	else
	{
		printf("param not correct!\n");
		isupload=false;
	}

	//init usb device
	usb_init();
	bus_count = usb_find_busses();
	if(bus_count<1)
	{
		printf("bus not found.\n");
		return -1;
	}
	device_count = usb_find_devices();
	if(device_count<1)
	{
		printf("device not found.\n");
		return -1;
	}
	// Check to see if each USB device matches the DigiSpark Vendor and Product IDs
	for (bus = usb_get_busses(); bus; bus = bus->next)
	{
		for (digispark = bus->devices; digispark; digispark = digispark->next)
		{
			if (digispark->descriptor.idVendor == DIGISPARKVID  && digispark->descriptor.idProduct == DIGISPARKPID)
			{
				p_handle = usb_open(digispark);
				break;
			}
		}
	}
	if(p_handle == NULL)
	{
		printf("device cannot opened.\n");
		return -1;
	}
	numInterfaces = digispark->config->bNumInterfaces;
	p_interface = &(digispark->config->interface[0].altsetting[0]);
	printf("begin reading data...\n");
	printf("press CTRL+C to end program.\n");
	//using while loop to read data form device
	while(true)
	{
		result = usb_control_msg(p_handle, (0x01 << 5) | 0x80, 0x01, 0, 0, &tmpchar, 1, 1000);
		if(result>0)
		{
			value.bvalue[0] = (byte)tmpchar;
			result = usb_control_msg(p_handle, (0x01 << 5) | 0x80, 0x01, 0, 0, &tmpchar, 1, 1000);
			if(result>=0)
			{
				value.bvalue[1] = (byte)tmpchar;
				printf("VOC(PPM):%d\n",value.ivalue);
				if(isupload ==true)
				{
					printf("uploading data to yeelink... ");
					if(upload_data_yeelink("api.yeelink.net",apikey,deviceid,sensorid,value.ivalue) == 0)
					printf("successed\n");
					else
					printf("error\n");
				}
			}
		}
	}
	//usb_close(p_handle);
	//getchar();
	return 0;
}
